﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace AutoTestingFramework.Core.Elements
{
    public class Element : IElement
    {
        private IWebElement _webElement;
        private ElementSelector _elementSelector;
        private string _tagName;

        public Element(IWebElement webElement, ElementSelector elementSelector)
        {
            this._webElement = webElement;
            this._elementSelector = elementSelector;
            this._tagName = webElement.TagName;
        }


        public ElementSelector ElementSelector
        {
            get { return _elementSelector; }
            set { _elementSelector = value; }
        }

        public string TagName
        {
            get { return _tagName; }
        }

        public string Value
        {
            get
            {
                if (_tagName == "input" || _tagName == "textarea")
                {
                    return this.Attributes.GetAttributeName("value");
                }
                else if (this.IsSelect)
                {
                    return string.Join(",", this.SelectedOptionValues);
                }
                else
                {
                    return this.Text;
                }
            }
        }

        public string Text
        {
            get
            {
                if (_tagName == "inupt" || _tagName == "textarea")
                {
                    return this.Value;
                }
                else
                {
                    return _webElement.Text;
                }
            }
        }

        public bool IsText
        {
            get
            {
                bool isText = false;
                switch (_tagName)
                {
                    case "input":
                        switch (this.Attributes.GetAttributeName("type").ToLower())
                        {
                            case "text":
                            case "email":
                            case "search":
                            case "url":
                            case "tel":
                            case "number":
                            case "password":
                            case "hidden":
                                isText = true;
                                break;
                        }

                        break;
                    case "textarea":
                        isText = true;
                        break;
                }

                return isText;
            }
        }

        public bool IsSelect
        {
            get { return _webElement.TagName.ToLower() == "select"; }
        }

        public bool IsMultipleSelect
        {
            get
            {
                if (this.IsSelect)
                {
                    SelectElement selectElement = new SelectElement(this._webElement);
                    return selectElement.IsMultiple;
                }
                else
                {
                    return false;
                }
            }
        }

        public IEnumerable<string> SelectedOptionValues
        {
            get
            {
                if (this.IsSelect)
                {
                    SelectElement selectElement = new SelectElement(this._webElement);
                    return selectElement.AllSelectedOptions.Select(x => x.GetAttribute("value"));
                }
                else
                {
                    return null;
                }
            }
        }

        public IEnumerable<string> SelectedOptionTextCollection
        {
            get
            {
                if (this.IsSelect)
                {
                    SelectElement selectElement = new SelectElement(this._webElement);
                    return selectElement.AllSelectedOptions.Select(x => x.Text);
                }
                else
                {
                    return null;
                }
            }
        }

        public int PosX
        {
            get { return _webElement.Location.X; }
        }

        public int PosY
        {
            get { return _webElement.Location.Y; }
        }

        public int Width
        {
            get { return _webElement.Size.Width; }
        }

        public int Height
        {
            get { return _webElement.Size.Height; }
        }

        public IElementAttributeSelector Attributes
        {
            get { return new ElementAttributeSelector(_webElement); }
        }


    }

    public class ElementAttributeSelector : IElementAttributeSelector
    {
        private IWebElement _webElement;

        public ElementAttributeSelector(IWebElement webElement)
        {
            _webElement = webElement;
        }

        public string GetAttributeName(string attributeName)
        {
            if (string.IsNullOrEmpty(attributeName))
                throw new ArgumentNullException("attributeName");

            return _webElement.GetAttribute(attributeName);
        }
    }
}
